import React, { 
  useEffect, 
  useRef, 
  useState, 
  useCallback,
  useMemo 
} from "react";
import "./server.css";
import { marked } from "marked";
import me from '../../assets/me.jpg';
import you from '../../assets/you.jpg';

interface MessageItem {
  text: string;
  isUser: boolean;
  html?: string;
}

interface VoiceRecognitionProps {
  transcript: string;
  onNewTranscript: (text: string) => void;
}

function Yuyin({ transcript, onNewTranscript }: VoiceRecognitionProps) {
  // WebSocket 连接
  const ws = useRef<WebSocket | null>(null);
  // 输入框
 const inputRef = useRef<HTMLInputElement>(null);
//  容器
   const chatContainerRef = useRef<HTMLDivElement>(null);
     const synth = useRef<SpeechSynthesis | null>(null);
    //  
  const utterance = useRef<SpeechSynthesisUtterance | null>(null);
   const [isConnected, setIsConnected] = useState(false);           // WebSocket连接状态
  // 消息列表
  const [messages, setMessages] = useState<MessageItem[]>([]);
  // 输入的文字
  const [typingText, setTypingText] = useState("");
  // 语音合成
  const [voices, setVoices] = useState<SpeechSynthesisVoice[]>([]);
  // 
  const [selectedVoice, setSelectedVoice] = useState<SpeechSynthesisVoice | null>(null);

  // 初始化 WebSocket
  const initWebSocket = useCallback(() => {
    ws.current = new WebSocket("ws://localhost:3001"); // 替换为你的WS地址
    // 连接成功回调
    ws.current.onopen = () => {
      console.log("WebSocket connected");
       setIsConnected(true);
    };
    // 
    ws.current.onmessage = (event) => {
      try {
        const response = JSON.parse(event.data);
        animateTyping(response.text); // 播放收到的消息
      } catch (error) {
        console.error("消息解析失败:", error);
      }
    };
// 连接断开 错误处理
    ws.current.onerror = (error) => {
console.error("WebSocket错误:", error);
      setIsConnected(false);
    };
    // 连接关闭回调
    ws.current.onclose = () => {
      console.log("WebSocket连接关闭");
      setIsConnected(false);
      // 3秒后尝试重连
      setTimeout(initWebSocket, 3000);
    
    };
  }, []);

  // 文字逐字显示动画
  const animateTyping = (text: string) => {
    let index = 0;
    setTypingText("");

    const type = () => {
      if (index < text.length) {
        setTypingText(prev => prev + text.charAt(index));
        index++;
        requestAnimationFrame(type);
      } else {
        setMessages(prev => [...prev, { text, isUser: false }]);
        setTypingText("");
        speak(text)
      }
    };
    type();
  };

  // 处理语音识别结果
  useEffect(() => {
    if (transcript) {
      sendMessage(transcript);
      onNewTranscript(""); // 清空转录文本
    }
  }, [transcript, onNewTranscript]);

  // 发送消息
  const sendMessage = useCallback((text: string) => {
    if (!text.trim()) return;

    // 添加到消息列表
        // const newMessage = { text, isUser: true };
    setMessages(prev => [...prev, { text, isUser: true }]);

    // 通过WebSocket发送
    if (ws.current?.readyState === WebSocket.OPEN) {
      ws.current.send(JSON.stringify({
        type: "message",
        text
      }));
    }

    // 清空输入框
    if (inputRef.current) inputRef.current.value = "";
  }, []);

  // 初始化语音合成
  useEffect(() => {
    synth.current = window.speechSynthesis;

    const loadVoices = () => {
      const availableVoices = synth.current?.getVoices() || [];
      setVoices(availableVoices);
      if (availableVoices.length > 0 && !selectedVoice) {
        setSelectedVoice(availableVoices[0]);
      }
    };

    loadVoices();
    synth.current.onvoiceschanged = loadVoices;

    return () => {
      synth.current?.onvoiceschanged = null;
  
    };
  }, [selectedVoice]);

  // 语音播报
 const speak=useCallback((text: string) => {

    if (!synth.current || !selectedVoice) return;

    synth.current.cancel(); // 取消当前播报

    utterance.current = new SpeechSynthesisUtterance(text);
    utterance.current.voice = selectedVoice;
    utterance.current.lang = "zh-CN";
     utterance.current.rate = 1.0; // 语速
    utterance.current.pitch = 1.0; // 音调
    // 错误处理
    utterance.current.onerror = (event) => {
      console.error("语音播报失败:", event.error);
    };

    // 开始播报
    synth.current.speak(utterance.current);
  }, [selectedVoice]);

  // 自动滚动到底部
  useEffect(() => {
    if (chatContainerRef.current) {
      chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
    }
  }, [messages, typingText]);

  // 初始化
  useEffect(() => {
    initWebSocket();
    return () => {
      ws.current?.close();
      synth.current?.cancel();
    };
  }, [initWebSocket]);

  const renderedMessages = useMemo(() => {
    return messages.map((msg) => ({
      ...msg,
      html: marked(msg.text),
    }));
  }, [messages]);

  return (
    <div className="chat-container" ref={chatContainerRef}>
      <div className="header">
        <h2>智能语音助手</h2>
        状态: <span style={{ color: isConnected ? 'green' : 'red' }}>
            {isConnected ? '已连接' : '连接中...'}
          </span>
        <div className="voice-controls">
          
          <select
            value={selectedVoice?.name || ""}
            onChange={(e) => {
              const voice = voices.find(v => v.name === e.target.value);
              if (voice) {
                setSelectedVoice(voice)  
                 speak("测试语音"); // 测试新选择的语音;
              }
            }}
          >
            {voices.map(voice => (
              <option key={voice.name} value={voice.name}>
                {voice.name} ({voice.lang})
              </option>
            ))}
          </select>
        </div>
      </div>

      <div className="messages">
        {renderedMessages.map((msg, index) => (
          <Message key={index} item={msg} />
        ))}
        {typingText && (
          <div className="message-user">
            <img src={you} alt="Bot" className="avatar" />
            <div className="bubble">{typingText}</div>
          </div>
        )}
      </div>

      <div className="input-area">
        <input
          ref={inputRef}
          type="text"
          placeholder="输入消息..."
          onKeyPress={(e) => e.key === "Enter" && sendMessage(inputRef.current?.value || "")}
        />
        <button onClick={() => sendMessage(inputRef.current?.value || "")}>
          发送
        </button>
      </div>
    </div>
  );
}

const Message = React.memo(({ item }: { item: MessageItem }) => (
  <div className={ item.isUser ? "message-user" : "message-bot"}>
    <img src={item.isUser ? me : you} alt={item.isUser ? "User" : "Bot"} className="avatar" />
    <div 
      className="bubble"
      dangerouslySetInnerHTML={{ __html: item.html || item.text }}
    />
  </div>
));

export default Yuyin;